#import "BuildingViewer.h"

// The shared instance of BuildingViewer
static BuildingViewer* sharedBuildingViewer = nil;

/**
 * An BuildingViewer is an object representing the view that 
 * displays information regarding a given SFU building.
 *
 * Conforms to the UIScrollViewDelegate protocol.
 * Conforms to the MapBuildingSearchDelegate protocol.
 *
 * @author      James Lin
 * @version     2.2.7
 * @since       2.2.3
 * @see         UIScrollViewDelegate
 * @see         MapBuildingSearchDelegate
 * @see         FoursquareViewDelegate
 */
@implementation BuildingViewer

/**
 * Retrieve the shared instance of the building viewer.
 *
 * @return  the shared instance of BuildingViewer
 */
+ (BuildingViewer*)sharedBuildingViewer {
	@synchronized (self) {
		if (sharedBuildingViewer == nil) {
			sharedBuildingViewer = [[BuildingViewer alloc] init];
		}
		
		return sharedBuildingViewer;
	}
}

/**
 * Allocate the building viewer.
 *
 * @return  the newly allocated shared instance of BuildingViewer
 */
+ (id)alloc {
	@synchronized (self) {
		sharedBuildingViewer = [super alloc];
		return sharedBuildingViewer;
	}
}

/**
 * Retrieve a copy of the building viewer.
 *
 * @return  the shared instance of BuildingViewer
 */
+ (id)copy {
	@synchronized (self) {
		return sharedBuildingViewer;
	}
}

/**
 * Create a UILabel resized to its text content.
 *
 * @param labelContent  the text to place in the label
 * @param font          the font type and size of the text
 * @param textColor     the color of the text
 * @param padding       vertical padding on the top and bottom sides of the label
 * @return              a newly allocated UILabel with the specified text and style
 */
- (UILabel*)getLabelResizedToText:(NSString*)labelContent 
							 font:(UIFont*)font 
						textColor:(UIColor*)textColor 
						  padding:(CGFloat)padding {
	contentHeight += padding; // Top padding
	
	CGRect labelFrame = CGRectMake(HORIZONTAL_PADDING, contentHeight, 
								   VIEW_WIDTH-HORIZONTAL_PADDING*2, 0);
	UILabel* tempLabel = [[UILabel alloc] initWithFrame:labelFrame];
	
	// Set the label's text and properties
	tempLabel.text = labelContent;
	tempLabel.font = (font == nil) ? [UIFont systemFontOfSize:12.0] : font;
	tempLabel.textColor = (textColor == nil) ? [UIColor blackColor] : textColor;
	tempLabel.backgroundColor = [UIColor clearColor];
	tempLabel.numberOfLines = 0;
	
	// Resize the label to fit text
	CGRect frame = [tempLabel frame];
	CGSize size = [tempLabel.text sizeWithFont:tempLabel.font 
							 constrainedToSize:CGSizeMake(frame.size.width, CGFLOAT_MAX) 
								 lineBreakMode:UILineBreakModeWordWrap];
	
	frame.size.height = size.height;
	contentHeight += size.height + padding; // Label height + bottom padding
	[tempLabel setFrame:frame];
	
	return tempLabel;
}

/**
 * Update the navigation bar.
 */
- (void)updateNavigationBar {
	if (buildingInfo) {
		if (buildingInfo.eventList && [buildingInfo.eventList count] > 0) {
			UIBarButtonItem* rightButton;
			rightButton = [[UIBarButtonItem alloc] initWithTitle:@"View Events" 
														   style:UIBarButtonItemStyleBordered 
														  target:self 
														  action:@selector(viewEvents)];
			[self.navigationItem setRightBarButtonItem:rightButton];
			[rightButton release];
		} else {
			[self.navigationItem setRightBarButtonItem:nil];
		}
	}
}

/**
 * Display the building information in a new view.
 *
 * Pushes this view onto the navigation controller stack of the parent
 * view. Upon tapping the back button, the view is automatically 
 * popped off the top of the navigation stack.
 *
 * @param building       the building to display
 * @param navController  the navigation controller of the parent view
 * @param theDelegate    the delegate handling building search requests
 */
- (void)displayBuilding:(Building*)building 
		  navController:(UINavigationController*)navController 
			andDelegate:(id<MapBuildingSearchDelegate>)theDelegate {
	// Reset the building view
	for (UIView* subview in buildingInfoView.subviews) {
		[subview removeFromSuperview];
	}
	
	// Save the building information
	buildingInfo = building;
	contentHeight = 5;
	delegate = theDelegate;
	
	// Set navigation properties
	self.navigationItem.title = @"Building Info";
	[self updateNavigationBar];
	parentNav = navController;
	
	// Create the building's heading label and add to view
	NSString* heading;
	if (buildingInfo.mainAbbrev) {
		heading = [NSString stringWithFormat:@"%@ (%@)", 
				   buildingInfo.name, buildingInfo.mainAbbrev];
	} else {
		heading = [NSString stringWithFormat:@"%@", buildingInfo.name];
	}
	
	UILabel* headingLabel;
	headingLabel= [self getLabelResizedToText:heading 
										 font:[UIFont boldSystemFontOfSize:15.0]
									textColor:nil
									  padding:7];
	[buildingInfoView addSubview:headingLabel];
	[headingLabel release];
	
	
	// Create the building's sub heading label and add to view
	NSString* subHeading;
	if (buildingInfo.secondaryName) {
		if (buildingInfo.secondaryAbbrev) {
			subHeading = [NSString stringWithFormat:@"%@ (%@)", 
						  buildingInfo.secondaryName, buildingInfo.secondaryAbbrev];
		} else {
			subHeading = [NSString stringWithFormat:@"%@", buildingInfo.secondaryName];
		}
		
		UILabel* subHeadingLabel;
		subHeadingLabel = [self getLabelResizedToText:subHeading
												 font:[UIFont italicSystemFontOfSize:13.0]
											textColor:[UIColor darkGrayColor]
											  padding:0];
		[buildingInfoView addSubview:subHeadingLabel];
		[subHeadingLabel release];
	}
	
	// Create the building's image and add to view
	if (buildingInfo.buildingImages && [buildingInfo.buildingImages count] > 0) {
		if (imageView) {
			[imageView release];
			[pageControl release];
		}
		
		currentImageIndex = 0;
		NSString* imgFileName = [buildingInfo.buildingImages objectAtIndex:currentImageIndex];
		UIImage* img = [UIImage imageNamed:imgFileName];
		imageView = [[UIImageView alloc] initWithImage:img];
		
		imageView.center = CGPointMake(VIEW_WIDTH/2, imageView.center.y);
		imageView.frame = CGRectMake(imageView.frame.origin.x, 
									 contentHeight + 10,
									 imageView.frame.size.width,
									 imageView.frame.size.height);
		contentHeight += imageView.frame.size.height + 20;
		
		CGRect frame = CGRectMake(0, contentHeight - 8, VIEW_WIDTH, 10);
		pageControl = [[UIPageControl alloc] initWithFrame:frame];
		pageControl.currentPage = 0;
		pageControl.defersCurrentPageDisplay = NO;
		pageControl.numberOfPages = [buildingInfo.buildingImages count];
		[buildingInfoView addSubview:pageControl];
		
		// Acknowledge horizontal swipe gesture support
		UISwipeGestureRecognizer *rightSwipeGesture;
		rightSwipeGesture = [UISwipeGestureRecognizer alloc];
		[rightSwipeGesture initWithTarget:self 
									   action:@selector(handleRightSwipeGesture:)];
		rightSwipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
		
		UISwipeGestureRecognizer *leftSwipeGesture;
		leftSwipeGesture = [UISwipeGestureRecognizer alloc];
		[leftSwipeGesture initWithTarget:self 
								   action:@selector(handleLeftSwipeGesture:)];
		leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
		
		imageView.userInteractionEnabled = YES;
		[imageView addGestureRecognizer:rightSwipeGesture];
		[imageView addGestureRecognizer:leftSwipeGesture];
		
		[buildingInfoView addSubview:imageView];
		
	}
	
	// Create the building's description label and add to view
	UILabel* descLabel;
	descLabel = [self getLabelResizedToText:buildingInfo.description
									   font:[UIFont systemFontOfSize:13.0]
								  textColor:nil
									padding:10];
	[buildingInfoView addSubview:descLabel];
	[descLabel release];
	
	UIView* foursquareView;
	foursquareView = [[FoursquareManager sharedFoursquareManager] getFoursquareViewWithDelegate:self];
	foursquareView.frame = CGRectMake(foursquareView.frame.origin.x, 
									  contentHeight + 20,
									  foursquareView.frame.size.width,
									  foursquareView.frame.size.height);
	foursquareView.center = CGPointMake(VIEW_WIDTH/2, foursquareView.center.y);
	contentHeight += foursquareView.frame.size.height + 20;
	
	buildingInfoView.contentSize = CGSizeMake(buildingInfoView.frame.size.width,
											  contentHeight);
	[buildingInfoView addSubview:foursquareView];

	
	// Display the building view
	[self.view addSubview:buildingInfoView];
	[parentNav pushViewController:self animated:YES];
}

/**
 * Get the possible names for the Foursquare view delegate.
 *
 * @return  the list of possible names for same venue
 * @see     FoursquareViewDelegate
 */
- (NSArray*)getPossibleVenueNames {
	NSMutableArray* names = [NSMutableArray array];
	[names addObject:buildingInfo.name];
	[names addObjectsFromArray:buildingInfo.buildingTags];
	
	return names;
}

/**
 * Get the Foursquare venue location.
 *
 * @return  the venue location
 * @see     FoursquareViewDelegate
 */
- (CLLocationCoordinate2D)getVenueLocation {
	CLLocationCoordinate2D location;
	location.latitude = buildingInfo.loc.latitude;
	location.longitude = buildingInfo.loc.longitude;
	
	return location;
}

/**
 * Helper method to view events at the building.
 */
- (void)viewEvents {
	EventManager* em = [EventManager sharedEventManager];
	[em setViewBuildingDelegate:self];
	[em displayEvents:buildingInfo.eventList navController:self.navigationController];
}

/**
 * Handle a building search request.
 *
 * @param building  the building of which a search is requested
 * @param isNew     will instruct callee as to what type of search request is occuring
 */
- (void)searchRequestByBuilding:(Building*)building isNew:(BOOL)isNew {
	[delegate searchRequestByBuilding:building isNew:isNew];
	[parentNav popViewControllerAnimated:NO];
}

/**
 * Handle the right swipe gesture.
 */
- (IBAction)handleRightSwipeGesture:(UIGestureRecognizer*)sender {
	if (imageView && buildingInfo.buildingImages) {
		NSInteger index = currentImageIndex;
		NSInteger count = [buildingInfo.buildingImages count];
		
		index++;
		index = (index >= count) ? 0 : index;
		currentImageIndex = index;
		pageControl.currentPage = currentImageIndex;
		
		//NSLog(@"Photo %d of %d", pageControl.currentPage, pageControl.numberOfPages);
		
		NSString* imgFileName = [buildingInfo.buildingImages objectAtIndex:currentImageIndex];
		[imageView setImage:[UIImage imageNamed:imgFileName]];
	}
}

/**
 * Handle the left swipe gesture.
 */
- (IBAction)handleLeftSwipeGesture:(UIGestureRecognizer*)sender {
	if (imageView && buildingInfo.buildingImages) {
		NSInteger index = currentImageIndex;		
		NSInteger count = [buildingInfo.buildingImages count];
		
		index--;
		index = (index < 0) ? (count - 1) : index;
		currentImageIndex = index;
		pageControl.currentPage = currentImageIndex;
		
		//NSLog(@"Photo %d of %d", pageControl.currentPage, pageControl.numberOfPages);
		
		NSString* imgFileName = [buildingInfo.buildingImages objectAtIndex:currentImageIndex];
		[imageView setImage:[UIImage imageNamed:imgFileName]];
	}
}

/**
 * Handle the single finger double tap gesture.
 *
 * Resets the zoom scale to default.
 */
- (IBAction)handleSingleFingerDoubleTap:(UIGestureRecognizer*)sender {
	[buildingInfoView setZoomScale:1.0 animated:YES];
}

/**
 * Reset the view prior to it appearing.
 */
- (void)viewWillAppear:(BOOL)animated {
	[self updateNavigationBar];
	[super viewWillAppear:YES];
}

/**
 * Initialize the building viewer.
 */
- (id)initWithNibName:(NSString *)nibNameOrNil 
			   bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
		// Create the scrollable building view and set its properties
		buildingInfoView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 
																	   VIEW_WIDTH, 
																	   VIEW_HEIGHT)];
		buildingInfoView.backgroundColor = [UIColor lightGrayColor];
		buildingInfoView.contentSize = CGSizeMake(VIEW_WIDTH, VIEW_HEIGHT+50);
		buildingInfoView.minimumZoomScale = MIN_ZOOM_SCALE;
		buildingInfoView.maximumZoomScale = MAX_ZOOM_SCALE;
		buildingInfoView.clipsToBounds = YES;
    }
	
    return self;
}

/**
 * Deallocate the building viewer.
 */
- (void)dealloc {
	delegate = nil;
	parentNav = nil;
	[pageControl release], pageControl = nil;
	[imageView release], imageView = nil;
	[buildingInfo release], buildingInfo = nil;
	[buildingInfoView release], buildingInfoView = nil;
	[sharedBuildingViewer release], sharedBuildingViewer = nil;
    [super dealloc];
}

@end
